

#include "HeaderFiles.h"

#include "comm_struct.h"
#include "uart_comm_hdl.h"

volatile uint8_t set_systemtime_flg = 0;
volatile uint8_t interrupt_analysis_flg = 0;
volatile uint64_t synchro_time_temp[2] = {0,0};

volatile uint8_t frame_analysis_protect = 0;

static uint8_t databuf_temp[50];

// MCU send to naviagtion data struct
STR_UPLOAD_SPEED      commSpd;
STR_UPLOAD_ENCODER    commEncoder;
STR_UPLOAD_IMU        commImuRaw;
STR_UPLOAD_LIGHTFLOW  commLightflow;
STR_UPLOAD_WALL       commWall;
STR_UPLOAD_CHARGE     commCharge;
STR_UPLOAD_CLIFF      commCliff;
STR_UPLOAD_BUMPER     commBumper;
STR_UPLOAD_KEY        commKey;
STR_UPLOAD_DROP       commDrop;
STR_UPLOAD_CURRENT    commCurrent;
STR_UPLOAD_EVENT      commEvent;
STR_UPLOAD_BMS_MANAGE commBmsManage;
STR_UPLOAD_MATERIAL   commMaterial;


// MCU send to naviagtion frame struct
STR_COMM_FRAME  uploadframeSpd = {.head_H = FRAME_HEAD_H, .head_L = FRAME_HEAD_L, .cmd_ID = ID_SPEED_UPLOAD,      \
								  .length = 1 + DATA_LEGTH_SPEED, .databuf = (&commSpd.data[2])};

STR_COMM_FRAME  uploadframeEncoder = {.head_H = FRAME_HEAD_H, .head_L = FRAME_HEAD_L, .cmd_ID = ID_ENCODER_UPLOAD, \
								      .length = 1 + DATA_LEGTH_ENCODER, .databuf = (&commEncoder.data[2])};

STR_COMM_FRAME  uploadframeImuRaw = {.head_H = FRAME_HEAD_H, .head_L = FRAME_HEAD_L, .cmd_ID = ID_IMU_RAW_UPLOAD,  \
								     .length = 1 + DATA_LEGTH_IMU_RAW, .databuf = (&commImuRaw.data[2])};

STR_COMM_FRAME  uploadframeLightflow = {.head_H = FRAME_HEAD_H, .head_L = FRAME_HEAD_L, .cmd_ID = ID_LIGHTFLOW_UPLOAD,  \
								        .length = 1 + DATA_LEGTH_LIGHTFLOW, .databuf = (&commLightflow.data[0])};
									
STR_COMM_FRAME  uploadframeWall = {.head_H = FRAME_HEAD_H, .head_L = FRAME_HEAD_L, .cmd_ID = ID_WALL_UPLOAD,  \
								   .length = 1 + DATA_LEGTH_WALL, .databuf = (&commWall.data[0])};

STR_COMM_FRAME  uploadframeCharge = {.head_H = FRAME_HEAD_H, .head_L = FRAME_HEAD_L, .cmd_ID = ID_CHARGE_POS_UPLOAD,  \
								   .length = 1 + DATA_LEGTH_CHARGE_POS, .databuf = (&commCharge.data[0])};
								   
STR_COMM_FRAME  uploadframeCliff = {.head_H = FRAME_HEAD_H, .head_L = FRAME_HEAD_L, .cmd_ID = ID_CLIFF_UPLOAD,  \
								   .length = 1 + DATA_LEGTH_CLIFF, .databuf = (&commCliff.data[0])};

STR_COMM_FRAME  uploadframeBumper = {.head_H = FRAME_HEAD_H, .head_L = FRAME_HEAD_L, .cmd_ID = ID_BUMPER_UPLOAD,  \
								   .length = 1 + DATA_LEGTH_BUMPER, .databuf = (&commBumper.data[0])};

STR_COMM_FRAME  uploadframeKey = {.head_H = FRAME_HEAD_H, .head_L = FRAME_HEAD_L, .cmd_ID = ID_KEY_STATUS_UPLOAD,  \
								   .length = 1 + DATA_LEGTH_KEY, .databuf = (&commKey.data[0])};

STR_COMM_FRAME  uploadframeDrop = {.head_H = FRAME_HEAD_H, .head_L = FRAME_HEAD_L, .cmd_ID = ID_DROP_STATUS_UPLOAD,  \
								   .length = 1 + DATA_LEGTH_DROP_STATUS, .databuf = (&commDrop.data[0])};

STR_COMM_FRAME  uploadframeCurrent = {.head_H = FRAME_HEAD_H, .head_L = FRAME_HEAD_L, .cmd_ID = ID_CURRENT_UPLOAD,  \
								   .length = 1 + DATA_LEGTH_CURRENT, .databuf = (&commCurrent.data[2])};

STR_COMM_FRAME  uploadframeEvent = {.head_H = FRAME_HEAD_H, .head_L = FRAME_HEAD_L, .cmd_ID = ID_EVENT_UPLOAD,  \
								   .length = 1 + DATA_LEGTH_EVENT, .databuf = (&commEvent.data[0])};

STR_COMM_FRAME  uploadframeBmsManage = {.head_H = FRAME_HEAD_H, .head_L = FRAME_HEAD_L, .cmd_ID = ID_BMS_MANAGE_UPLOAD,  \
								   .length = 1 + DATA_LEGTH_BMS, .databuf = (&commBmsManage.data[0])};

STR_COMM_FRAME  uploadframeMaterial = {.head_H = FRAME_HEAD_H, .head_L = FRAME_HEAD_L, .cmd_ID = ID_MATERIAL_UPLOAD,  \
								   .length = 1 + DATA_LEGTH_MATERIAL, .databuf = (&commMaterial.data[0])};


// Naviagtion send to MCU data struct
STR_COMM_SPEED_SET  dataSpdSet;
STR_COMM_TIME_SET   dataTimeSet;
STR_COMM_LED_SET    dataLedSet;
STR_COMM_CHARGE_SET dataChargeSet;
STR_COMM_CLEAN_SET  dataCleanSet;
STR_COMM_MOTOR_SET  dataMotorSet;
STR_COMM_HEARTBEAT  dataHeartbeat;
STR_COMM_LIGHTMODE  dataLightModeSet;
STR_COMM_BRUSH_SET  dataBrushSet;								

STR_COMM_SHIELD_CLIFF dataShieldCliff;
STR_COMM_SHIELD_CLIFF dataShieldCliff_A;
						   

// Naviagtion send to MCU frame struct
STR_COMM_FRAME  cmdframTimeSet   = {.length = 1 + DATA_LEGTH_TIME_SET,  .databuf = &dataTimeSet.data[0]};
STR_COMM_FRAME  cmdframSpdSet    = {.length = 1 + DATA_LEGTH_SPEED_SET, .databuf = &dataSpdSet.data[0] };
STR_COMM_FRAME  cmdframLedSet    = {.length = 1 + DATA_LEGTH_LED_SET,   .databuf = &dataLedSet.data    };
STR_COMM_FRAME  cmdframChargeSet = {.length = 1 + DATA_LEGTH_CHARGE_SET,.databuf = &dataChargeSet.data };
STR_COMM_FRAME  cmdframCleanSet  = {.length = 1 + DATA_LEGTH_CLEAN_SET, .databuf = &dataCleanSet.data  };
STR_COMM_FRAME  cmdframMotorSet  = {.length = 1 + DATA_LEGTH_MOTOR_SET, .databuf = &dataMotorSet.data  };
STR_COMM_FRAME  cmdframHeartbeat = {.length = 1 + DATA_LEGTH_HEARTBEAT, .databuf = &dataHeartbeat.data };
STR_COMM_FRAME  cmdframlightmodeset = {.length = 1 + DATA_LEGTH_LIGHTMODE_SET, .databuf = &dataLightModeSet.data};
STR_COMM_FRAME  cmdframBrushSet  = {.length = 1 + DATA_LEGTH_BRUSH_SET, .databuf = &dataBrushSet.data[0] };

STR_COMM_FRAME  cmdframShieldCliff   = {.length = 1 + DATA_LEGTH_SHIELD_CLIFF, .databuf = &dataShieldCliff.data};
STR_COMM_FRAME  cmdframShieldCliff_A = {.length = 1 + DATA_LEGTH_SHIELD_CLIFF, .databuf = &dataShieldCliff_A.data};


STR_COMM_FRAME *cmdframGroup[10] = { &cmdframTimeSet,     \
									&cmdframSpdSet,       \
									&cmdframLedSet,       \
									&cmdframChargeSet,    \
									&cmdframCleanSet,     \
									&cmdframMotorSet,     \
									&cmdframlightmodeset, \
									&cmdframBrushSet,     \
									&cmdframShieldCliff,  \
									&cmdframShieldCliff_A };
/*!
    \brief      
    \param[in]  none
    \param[out] none
    \retval     none
*/
void comm_struct_init(void)
{
	
	// MCU send to naviagtion
	commSpd.real.time = 0;
	commSpd.real.speedwheel_L = 0;
	commSpd.real.speedwheel_R = 0;

	commEncoder.real.time = 0;
	commEncoder.real.m1_value = 0;
	commEncoder.real.m2_value = 0;
	
}


/*!
    \brief      
    \param[in]  none
    \param[out] none
    \retval     none
*/

void comm_frame_upload(STR_COMM_FRAME *frame, STR_RINGBUF* bufhdl)
{
	uint16_t frame_id    = 0;
	uint16_t crc_value   = 0;
	uint16_t data_length = frame->length - 1;
	
	uint8_t *databuf_p = frame->databuf;
	
	static uint16_t upload_cnt = 0;
	
	upload_cnt++;
	
	frame_id = upload_cnt;

	frame->frame_ID_H = ((frame_id >> 8) & 0x00FF);
	frame->frame_ID_L = (frame_id & 0x00FF);
	
	databuf_temp[0] = frame->cmd_ID;
	
	for(uint8_t i=1;i<(data_length+1);i++)
	{
		databuf_temp[i] = *(databuf_p++);
	}
	
	crc_value = GetCRC((uint8_t*)(databuf_temp), frame->length);
	
	frame->CRC_H = ((crc_value >> 8) & 0x00FF);
	frame->CRC_L = (crc_value & 0x00FF);
	
	#if 1
	ringBufWrite(bufhdl, (char*)frame, 6);
	ringBufWrite(bufhdl, (char*)frame->databuf, data_length);
	ringBufWrite(bufhdl, (char*)(&frame->CRC_H), 1);
    ringBufWrite(bufhdl, (char*)(&frame->CRC_L), 1);
	#endif
}


/*!
    \brief      
    \param[in]  none
    \param[out] none
    \retval     none
*/
uint8_t comm_frame_store(STR_COMM_FRAME *frame, uint8_t *databuf)
{
	uint8_t store_length = 0;
	uint8_t crc_rslt;
	uint16_t data_length = frame->length - 1;
	
	#if 0
	frame->length = databuf[4];
	#endif

	frame->CRC_H = databuf[6 + data_length + 0];
	frame->CRC_L = databuf[6 + data_length + 1];	
	
	crc_rslt = checkCRC(&databuf[5], (data_length + 1), ((frame->CRC_H << 8) | (frame->CRC_L)));
	
	if(crc_rslt != 0)
	{
		frame->head_H     = databuf[0];
		frame->head_L     = databuf[1];
		frame->frame_ID_H = databuf[2];
		frame->frame_ID_L = databuf[3];
		frame->cmd_ID     = databuf[5];
		
		memcpy(frame->databuf, &databuf[6], data_length);
		
	    store_length = frame->length;
	}
	
	else
	{
		store_length = 0;
	}
	
	return store_length;
}



/*!
    \brief      
    \param[in]  none
    \param[out] none
    \retval     none
*/
uint8_t comm_frame_handle(STR_COMM_FRAME *frame, uint8_t *databuf, uint8_t ack)
{
	uint16_t store_length = 0;

	store_length = comm_frame_store(frame, databuf);

	if((store_length != 0) && (ack == 1))
	{
		comm_frame_upload(frame, &commUARTSendbuf);	
	}

	return store_length;
}


/*!
    \brief      
    \param[in]  none
    \param[out] none
    \retval     none
*/
uint8_t comm_frame_analysis(STR_COMM_FRAME *frame[], STR_RINGBUF* bufhdl)	
{
	uint8_t  reslt = 0;
	static uint8_t  databuf[SCI_RECBUF_LEN];
	uint16_t length;
	uint16_t cmdId = 0;
	uint16_t store_length = 0;
	
	length = ringBufRead(bufhdl, (char*)databuf, SCI_RECBUF_LEN);
	
	for(uint16_t i=0;i<length;i++)
	{
		if((databuf[i] == FRAME_HEAD_H) && (databuf[i+1] == FRAME_HEAD_L))
		{
			store_length = 0;
			cmdId = databuf[i+5];
			
 			switch(cmdId)
			{
				case ID_CMD_TIME_SET:
					store_length = comm_frame_handle(frame[STORE_NUM_TIME_SET], &databuf[i], 1);
					if(store_length != 0)
					{	
						#if 1
						volatile uint64_t synchro_time = 0;
						synchro_time = (uint64_t)(dataTimeSet.real.time / 1000);
						set_system_runingtime(synchro_time);
						
						#else
						if((set_systemtime_flg == 0) && (interrupt_analysis_flg == 0))
						{
							set_systemtime_flg = 2;						
						}
						else if((interrupt_analysis_flg == 1) || (set_systemtime_flg != 0))
						{
							set_systemtime_flg--;
							interrupt_analysis_flg = 0;
													
							synchro_time_temp[set_systemtime_flg] = dataTimeSet.real.time;
							
							if(set_systemtime_flg == 0)
							{
								volatile uint64_t synchro_time_erro = 0;
								
								synchro_time_erro = synchro_time_temp[0] - synchro_time_temp[1];
								
								if(synchro_time_erro < SYNCRO_TIME_ERRO_MAX)
								{
									volatile uint64_t synchro_time = 0;			
									#if 0
									synchro_time = (uint64_t)(dataTimeSet.real.time * SET_SYNCHRO_TIME_SF);
									#else
									synchro_time = (uint64_t)(dataTimeSet.real.time / 1000);
									#endif
									set_system_runingtime(synchro_time);								
								}
							}
						}
						#endif
					}
					
				break;
									
				case ID_CMD_SPEED_SET:
					store_length = comm_frame_handle(frame[STORE_NUM_SPEED_SET], &databuf[i], 0);
					userHdl.assis.speedcmdcnt = 0;
					
				break;
				
				case ID_CMD_LED_SET:
					store_length = comm_frame_handle(frame[STORE_NUM_LED_SET], &databuf[i], 1);
					
				break;
				
				case ID_CMD_CHARGE_SET:
					store_length = comm_frame_handle(frame[STORE_NUM_CHARGE_SET], &databuf[i], 1);
					
				break;
				
				case ID_CMD_CLEAN_SET:	
					store_length = comm_frame_handle(frame[STORE_NUM_CLEAN_SET], &databuf[i], 1);
					
				break;				
				
				case ID_CMD_MOTOR_SET:	
					store_length = comm_frame_handle(frame[STORE_NUM_MOTOR_SET], &databuf[i], 1);
					
				break;
				
				case ID_CMD_HEARTBEAT:
					reslt++;
				break;
				
				case ID_CMD_LIGHTMODE_SET:
					store_length = comm_frame_handle(frame[STORE_NUM_LIGHTMODE_SET], &databuf[i], 1);
				break;
				
				
				case ID_CMD_GS2_PARAM_GET:
					reslt++;
					userHdl.assis.gs2_param_upload = 1;
				break;
				
				
				case ID_CMD_BRUSH_SET:
					
					store_length = comm_frame_handle(frame[STROE_NUM_BRUSH_SET], &databuf[i], 1);

				break;
				
				case ID_CMD_SHIELD_CLIFF:
					
					store_length = comm_frame_handle(frame[STORE_NUM_SHIELD_CLIFF], &databuf[i], 0);
			
				break;
				
				case ID_CMD_SHIELD_CLIFF_A:
					
					store_length = comm_frame_handle(frame[STORE_NUM_SHIELD_CLIFF_A], &databuf[i], 1);

				break;
								
			}
			
			if(store_length != 0)   reslt++;			
			
			i = i + store_length;
		}		
	}
	
	return reslt;
}


/*!
    \brief      
    \param[in]  none
    \param[out] none
    \retval     none
*/

void upload_uartcomm_data(uint8_t cmd_id)
{
	switch(cmd_id)
	{
		// wheel motor speed (50Hz/20ms)
		case ID_SPEED_UPLOAD:
			
			commSpd.real.time = (uint16_t)get_system_runingtime();
			commSpd.real.speedwheel_L = userHdl.signal.wheel_speed_rps[WHEEL_LIFT] * LINEAR_SPEED_SF;
			commSpd.real.speedwheel_R = userHdl.signal.wheel_speed_rps[WHEEL_RIGHT] * LINEAR_SPEED_SF;
			comm_frame_upload(&uploadframeSpd, &commUARTSendbuf);
		
		break;
		
		// wheel motor encoder value (30Hz/30ms)
		case ID_ENCODER_UPLOAD:
			
			commEncoder.real.time = (uint16_t)get_system_runingtime();
			#if 0
			commEncoder.real.m1_value = get_encoder_displacement(WHEEL_LIFT);
			commEncoder.real.m2_value = get_encoder_displacement(WHEEL_RIGHT);
			#else
			commEncoder.real.m1_value = get_encoder_accumulate(&encoderAccum[WHEEL_LIFT]);
			commEncoder.real.m2_value = get_encoder_accumulate(&encoderAccum[WHEEL_RIGHT]);			
			#endif
			comm_frame_upload(&uploadframeEncoder, &commUARTSendbuf);
		
		break;
		
		// IMU gyro and accele RAW data (20Hz/50ms)
		case ID_IMU_RAW_UPLOAD:
			
			commImuRaw.real.time = (uint16_t)get_system_runingtime();
			commImuRaw.real.gyro[0]  = userHdl.signal.gyro[0];
			commImuRaw.real.gyro[1]  = userHdl.signal.gyro[1];
			commImuRaw.real.gyro[2]  = userHdl.signal.gyro[2];
			commImuRaw.real.accel[0] = userHdl.signal.accel[0];
			commImuRaw.real.accel[1] = userHdl.signal.accel[1];
			commImuRaw.real.accel[2] = userHdl.signal.accel[2];
			
			comm_frame_upload(&uploadframeImuRaw, &commUARTSendbuf);		
		break;
		
		// lightflow sensor data (30Hz/30ms)
		case ID_LIGHTFLOW_UPLOAD:
			
			commLightflow.real.time = (uint16_t)get_system_runingtime();
			commLightflow.real.flowX = userHdl.signal.lightflowX;
			commLightflow.real.flowY = userHdl.signal.lightflowY;
			commLightflow.real.quality = userHdl.signal.lightflow_imagequality;
			commLightflow.real.mode = userHdl.signal.lightmode;
		
			comm_frame_upload(&uploadframeLightflow, &commUARTSendbuf);
		break;
		
		
		// wall sensor data (30Hz/30ms)
		case ID_WALL_UPLOAD:
			
			commWall.real.time = (uint16_t)get_system_runingtime();
		
			#if TOF050F_EN
			commWall.real.distance[0] = (uint16_t)userHdl.signal.tof050_rslt[0];
			commWall.real.distance[1] = (uint16_t)userHdl.signal.tof050_rslt[1];
			#elif SDS1A015_EN
			commWall.real.distance[0] = (uint16_t)userHdl.signal.real.wall_sensor[0];
			commWall.real.distance[1] = (uint16_t)userHdl.signal.real.wall_sensor[1];
			#endif
			
			comm_frame_upload(&uploadframeWall, &commUARTSendbuf);
		break;
		
		
		// charge position sensor(20Hz/50ms)
		case ID_CHARGE_POS_UPLOAD:
			
			commCharge.real.time = (uint16_t)get_system_runingtime();
			commCharge.real.chargeSignal[0] = userHdl.signal.chargeSignal[NUM_INFRARED_BACK_LEFT];
			commCharge.real.chargeSignal[1] = userHdl.signal.chargeSignal[NUM_INFRARED_BACK_RIGHT];
			commCharge.real.chargeSignal[2] = userHdl.signal.chargeSignal[NUM_INFRARED_LEFT];
			commCharge.real.chargeSignal[3] = userHdl.signal.chargeSignal[NUM_INFRARED_RIGHT];
		
			comm_frame_upload(&uploadframeCharge, &commUARTSendbuf);
		
		break;
		
		
		// cliff sensor data 
		case ID_CLIFF_UPLOAD:
			
			commCliff.real.time = (uint16_t)get_system_runingtime();
			commCliff.real.sta_left  = userHdl.signal.cliff_flg[NUM_CLIFF_LEFT];
			commCliff.real.sta_right = userHdl.signal.cliff_flg[NUM_CLIFF_RIGHT];
			commCliff.real.sta_front_left  = userHdl.signal.cliff_flg[NUM_CLIFF_FRONT_LEFT];
			commCliff.real.sta_front_right = userHdl.signal.cliff_flg[NUM_CLIFF_FRONT_RIGHT];
			commCliff.real.sta_back_left  = userHdl.signal.cliff_flg[4];
			commCliff.real.sta_back_right = userHdl.signal.cliff_flg[5];
		
			comm_frame_upload(&uploadframeCliff, &commUARTSendbuf);
		
		break;
		
		
		// Bumper status data
		case ID_BUMPER_UPLOAD:
			
			commBumper.real.time = (uint16_t)get_system_runingtime();
			commBumper.real.sta_left = !userHdl.signal.bumper[0];
			commBumper.real.sta_right = !userHdl.signal.bumper[1];
			commBumper.real.sta_left_right = !((userHdl.signal.bumper[0]) || (userHdl.signal.bumper[1]));
		
			comm_frame_upload(&uploadframeBumper, &commUARTSendbuf);
		
		break;
		
		// key status data 
		case ID_KEY_STATUS_UPLOAD:
			
			commKey.real.time = (uint16_t)get_system_runingtime();
			commKey.data[2] = userHdl.signal.keyevent;
		
			comm_frame_upload(&uploadframeKey, &commUARTSendbuf);
		
		break;
		
		// wheel lift check
		case ID_DROP_STATUS_UPLOAD:
			
			commDrop.real.time = (uint16_t)get_system_runingtime();
			commDrop.real.sta_left = !userHdl.signal.wheellift[WHEEL_LIFT];
			commDrop.real.sta_right = !userHdl.signal.wheellift[WHEEL_RIGHT];
		
			comm_frame_upload(&uploadframeDrop, &commUARTSendbuf);
		
		break;
		
		// motor current (5Hz / 200ms)
		case ID_CURRENT_UPLOAD:
			
			commCurrent.real.time           = (uint16_t)get_system_runingtime();
			commCurrent.real.mainBrush      = userHdl.signal.real.is_mainbrush;
			commCurrent.real.dustSuctionFan = userHdl.signal.real.is_dustsuctionfan;
			commCurrent.real.leftBrush      = userHdl.signal.real.is_leftbrush;
			commCurrent.real.rightBrush     = userHdl.signal.real.is_rightbrush;
			commCurrent.real.wheelleft      = userHdl.signal.real.is_wheel[WHEEL_LIFT];
			commCurrent.real.wheelright     = userHdl.signal.real.is_wheel[WHEEL_RIGHT];
		
			comm_frame_upload(&uploadframeCurrent, &commUARTSendbuf);
		
		break;
		
		
		case ID_EVENT_UPLOAD:
			
			commEvent.real.time = (uint16_t)get_system_runingtime();
			commEvent.real.brake_distance =
					0.5f * (userHdl.signal.break_distance[WHEEL_LIFT] + userHdl.signal.break_distance[WHEEL_RIGHT]);
			
			commEvent.real.brake_Status = userHdl.ctrl.systemstop;
			commEvent.real.bumper_L = !userHdl.signal.bumper[0];
			commEvent.real.bumper_R = !userHdl.signal.bumper[1];
		
			commEvent.real.cliff_1 = userHdl.signal.cliff_flg[NUM_CLIFF_LEFT];
			commEvent.real.cliff_2 = userHdl.signal.cliff_flg[NUM_CLIFF_RIGHT];
			commEvent.real.cliff_3 = userHdl.signal.cliff_flg[NUM_CLIFF_FRONT_LEFT];
			commEvent.real.cliff_4 = userHdl.signal.cliff_flg[NUM_CLIFF_FRONT_RIGHT];
			
			commEvent.real.cliff_5 = userHdl.signal.cliff_flg[4];
			commEvent.real.cliff_6 = userHdl.signal.cliff_flg[5];
		
			comm_frame_upload(&uploadframeEvent, &commUARTSendbuf);
			
		break;
		
		case ID_BMS_MANAGE_UPLOAD:
			
			commBmsManage.real.time = (uint16_t)get_system_runingtime();
		
			#if 0
			if((userHdl.fault.bit.UVP == 1) || (userHdl.warn.bit.UVP == 1))
			{
				commBmsManage.real.status = 2;
			}
			else
			{
				commBmsManage.real.status = 0;
			}
			#else
			commBmsManage.real.status = userHdl.signal.chargestatus;
			#endif
			
			commBmsManage.real.level = (uint8_t)userHdl.signal.battery_level;
			
			comm_frame_upload(&uploadframeBmsManage, &commUARTSendbuf);

			
		break;
		
		
		case ID_MATERIAL_UPLOAD:
			
			commMaterial.real.time = (uint16_t)get_system_runingtime();
			commMaterial.real.sort = userHdl.signal.material_sort;
			commMaterial.real.distance = 0;
		
			comm_frame_upload(&uploadframeMaterial, &commUARTSendbuf);
		
		break;	
	}
}





/*!
    \brief      
    \param[in]  none
    \param[out] none
    \retval     none
*/

void get_uartcomm_cmd(void)
{
	if(userHdl.ctrl.FSM == FSM_STATE_FAULT)
	{
		dataMotorSet.real.leftBrush      = 0;
		dataMotorSet.real.dustsuctionFan = 0;
		dataMotorSet.real.mainBrush      = 0;
		
		dataCleanSet.real.clean_mode = CLEAN_MOTOR_STOP;
		
		dataSpdSet.real.speedLinear = 0;
		dataSpdSet.real.speedAngle  = 0;
		
		#if 1
		memset((void *)&dataBrushSet, 0, sizeof(dataBrushSet));
		#endif
		
		
	}
	
	
	
	#if 0
	userHdl.ctrl.enable_dustfan   = dataMotorSet.real.dustsuctionFan;
	userHdl.ctrl.enable_edgebrush = dataMotorSet.real.leftBrush;
	userHdl.ctrl.enable_mainbrush = dataMotorSet.real.mainBrush;
	#elif 0
	
	uint8_t clean_motor_en = dataCleanSet.real.clean_mode;
	
	if(clean_motor_en == CLEAN_MOTOR_STOP)
	{
		userHdl.ctrl.enable_dustfan   = 0;
		userHdl.ctrl.enable_edgebrush = 0;
		userHdl.ctrl.enable_mainbrush = 0;
	}
	else if((clean_motor_en == CLEAN_MOTOR_RUN_FAST)  ||
			(clean_motor_en == CLEAN_MOTOR_RUN_MID)   || 
			(clean_motor_en == CLEAN_MOTOR_RUN_SLOW))
	{
		userHdl.ctrl.enable_dustfan   = 1;
		userHdl.ctrl.enable_edgebrush = 1;
		userHdl.ctrl.enable_mainbrush = 1;
	}		
	
	#else
	
	userHdl.ctrl.enable_edgebrush   = (dataBrushSet.real.leftBrush_speed  > 20) ? 1 : 0;
	userHdl.ctrl.enable_edgebrushX2 = (dataBrushSet.real.rightBrush_speed > 20) ? 1 : 0;
	userHdl.ctrl.enable_mainbrush   = (dataBrushSet.real.rollBrush_speed  > 20) ? 1 : 0;
	userHdl.ctrl.enable_dustfan     = (dataBrushSet.real.dustfan_speed    > 20) ? 1 : 0;
	userHdl.ctrl.enable_leftmop     = (dataBrushSet.real.leftMop_speed    > 20) ? 1 : 0;
	
	#if 0
	userHdl.ctrl.enable_rightmop    = (dataBrushSet.real.rightMop_speed   > 20) ? 1 : 0;
	#else
	userHdl.ctrl.enable_rightmop    = userHdl.ctrl.enable_leftmop;	
	#endif
	
	
	#endif	

	userHdl.ctrl.speedline_mps  = dataSpdSet.real.speedLinear * INV_LINEAR_SPEED_SF;
							
	userHdl.ctrl.speedangle_dps = dataSpdSet.real.speedAngle * ANGLE_SPEED_SF;
	userHdl.ctrl.speedangle_dps = MATH_sat(userHdl.ctrl.speedangle_dps, ANGLE_SPEED_MAX, -ANGLE_SPEED_MAX);
	userHdl.ctrl.speedangle_rads = dataSpdSet.real.speedAngle;
	
	
	userHdl.signal.ledstatus = dataLedSet.real.state;
	
	if(dataLightModeSet.real.mode == 1)
	{
		userHdl.ctrl.lightmode = 0;
	}
	else if(dataLightModeSet.real.mode == 2)
	{	
		userHdl.ctrl.lightmode = 1;
	}
		
	userHdl.ctrl.shield_cliff   = dataShieldCliff.real.en_shield;
	userHdl.ctrl.shield_cliff_A = dataShieldCliff_A.real.en_shield;
	
}




